CONSIGNAS El objetivo general es poder crear un modelo lineal simple para explicar el precio de venta de las propiedades en Capital Federal reportadas por la empresa Properati. Para ello es necesario realizar analisis exploratorios, limpieza del dataset y realizar los modelos. Vamos a utilizar datos del 2019 para no incorporar comportamientos atípicos ocasionados por la pandemia del COVID-19.
#Añado librerías necesarias
library(tidyverse)
library(corrr)
library(ggplot2)
#library(tidymodels)
#Leo los datos del dataSet
datos_propiedades <- read.csv("ar_properties.csv")
#Revisión datos con str
str(datos_propiedades)
'data.frame': 388891 obs. of 24 variables:
$ id : chr "S0we3z3V2JpHUJreqQ2t/w==" "kMxcmAS8NvrynGBVbMOEaQ==" "Ce3ojF+ZTOkB8d+LI9dpxg==" "AUGpj3raGmOCiulSMGIBPA==" ...
$ ad_type : chr "Propiedad" "Propiedad" "Propiedad" "Propiedad" ...
$ start_date : chr "2019-04-14" "2019-04-14" "2019-04-14" "2019-04-14" ...
$ end_date : chr "2019-06-14" "2019-04-16" "9999-12-31" "9999-12-31" ...
$ created_on : chr "2019-04-14" "2019-04-14" "2019-04-14" "2019-04-14" ...
$ lat : num -34.9 -34.6 NA -34.7 -34.7 ...
$ lon : num -54.9 -58.4 NA -58.8 -58.8 ...
$ l1 : chr "Uruguay" "Argentina" "Argentina" "Argentina" ...
$ l2 : chr "Maldonado" "Capital Federal" "Bs.As. G.B.A. Zona Norte" "Bs.As. G.B.A. Zona Oeste" ...
$ l3 : chr "Punta del Este" "Boedo" NA "Moreno" ...
$ l4 : chr NA NA NA "Moreno" ...
$ l5 : chr NA NA NA NA ...
$ l6 : logi NA NA NA NA NA NA ...
$ rooms : int 2 NA 2 2 2 4 NA 6 NA NA ...
$ bedrooms : int NA NA NA NA NA NA NA NA NA NA ...
$ bathrooms : int 1 NA 1 2 3 1 3 3 NA NA ...
$ surface_total : int 45 NA 200 460 660 NA 70 NA 1300 405 ...
$ surface_covered: int 40 NA NA 100 148 89 122 NA NA NA ...
$ price : int 13000 0 NA NA NA NA NA NA 0 NA ...
$ currency : chr "UYU" NA NA NA ...
$ price_period : chr "Mensual" "Mensual" NA "Mensual" ...
$ title : chr "Departamento - Roosevelt" "PH - Boedo" "Ituzaingo 1100 - $ 1 - Casa Alquiler" "Dr. Vera 300 - Consulte precio - Casa en Venta" ...
$ property_type : chr "Departamento" "PH" "Casa" "Casa" ...
$ operation_type : chr "Alquiler" "Venta" "Alquiler" "Venta" ...
#Revisión datos con Glipse
glimpse(datos_propiedades)
Rows: 388,891
Columns: 24
$ id <chr> "S0we3z3V2JpHUJreqQ2t/w==", "kMxcmAS8NvrynGBVbMOEaQ==", "Ce3ojF+ZTOkB8d+LI9dpxg==", "AUGpj3raGmOCiulSMGIBP…
$ ad_type <chr> "Propiedad", "Propiedad", "Propiedad", "Propiedad", "Propiedad", "Propiedad", "Propiedad", "Propiedad", "P…
$ start_date <chr> "2019-04-14", "2019-04-14", "2019-04-14", "2019-04-14", "2019-04-14", "2019-04-14", "2019-04-14", "2019-04…
$ end_date <chr> "2019-06-14", "2019-04-16", "9999-12-31", "9999-12-31", "2019-07-09", "2019-08-08", "2019-07-10", "2019-06…
$ created_on <chr> "2019-04-14", "2019-04-14", "2019-04-14", "2019-04-14", "2019-04-14", "2019-04-14", "2019-04-14", "2019-04…
$ lat <dbl> -34.94331, -34.63181, NA, -34.65471, -34.65495, -32.93547, -34.65183, -34.91213, -34.60338, NA, -34.59005,…
$ lon <dbl> -54.92966, -58.42060, NA, -58.79089, -58.78712, -60.68398, -58.65912, -54.84749, -58.43450, NA, -58.43672,…
$ l1 <chr> "Uruguay", "Argentina", "Argentina", "Argentina", "Argentina", "Argentina", "Argentina", "Uruguay", "Argen…
$ l2 <chr> "Maldonado", "Capital Federal", "Bs.As. G.B.A. Zona Norte", "Bs.As. G.B.A. Zona Oeste", "Bs.As. G.B.A. Zon…
$ l3 <chr> "Punta del Este", "Boedo", NA, "Moreno", "Moreno", "Rosario", "Ituzaingó", "José Ignacio", "Almagro", "Mir…
$ l4 <chr> NA, NA, NA, "Moreno", "Moreno", NA, "Ituzaingó", NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
$ l5 <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
$ l6 <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
$ rooms <int> 2, NA, 2, 2, 2, 4, NA, 6, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,…
$ bedrooms <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
$ bathrooms <int> 1, NA, 1, 2, 3, 1, 3, 3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1, NA, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
$ surface_total <int> 45, NA, 200, 460, 660, NA, 70, NA, 1300, 405, 352, 373, 360, 1325, 250, 80142, 101, NA, 54, 180, 36, 36, 4…
$ surface_covered <int> 40, NA, NA, 100, 148, 89, 122, NA, NA, NA, NA, NA, NA, 2, NA, NA, NA, NA, 54, 180, 33, 33, 34, 34, 34, 34,…
$ price <int> 13000, 0, NA, NA, NA, NA, NA, NA, 0, NA, 0, NA, NA, NA, NA, NA, 0, 0, 0, NA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ currency <chr> "UYU", NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ price_period <chr> "Mensual", "Mensual", NA, "Mensual", "Mensual", "Mensual", "Mensual", "Mensual", "Mensual", "Mensual", "Me…
$ title <chr> "Departamento - Roosevelt", "PH - Boedo", "Ituzaingo 1100 - $ 1 - Casa Alquiler", "Dr. Vera 300 - Consu…
$ property_type <chr> "Departamento", "PH", "Casa", "Casa", "Casa", "Casa", "Casa", "Casa", "Lote", "Lote", "Lote", "Lote", "Lot…
$ operation_type <chr> "Alquiler", "Venta", "Alquiler", "Venta", "Venta", "Venta", "Venta", "Alquiler", "Venta", "Venta", "Venta"…
#Clase de los datos
class(datos_propiedades) #DataFrame
[1] "data.frame"
Se observa que el dataframe está compeusto por 388,891 observaciones caracterizadas por 24 variables. 15 Variables de tipo caracter 8 Variables de tipo numérico 1 Variable de tipo lógico
Estas variables podrían agruparse tambíen del siguiente modo: 3 variables de fecha. 8 Variables describiendo la ubicación, dos de ellas de latitud y longitud, y 6 de ellas variables de texto describiendo ubicación desde país yendo a mayor detalle por ciudad, barrio, etc. 5 Variables descriptivas de la propiedad. 7 Variables descriptivas del condiciones de venta o arrendamiento. 1 Variable ID.
b.Quedarse con aquellos registros que: I.Pertenecen a Argentina y Capital Federal
datos_propiedades_filter <- datos_propiedades %>%
filter(l1 == "Argentina" , l2 == "Capital Federal")
datos_propiedades_filter
Aplicando este primer filtro por País y ciudad, tenemos ahora 124.327 propiedades.
II.Cuyo precio esta en dólares (USD)
datos_propiedades_filter <- datos_propiedades_filter %>%
filter(currency == "USD")
datos_propiedades_filter
Aplicando este segundo filtro tenemos 81.601 propiedades.
III.El tipo de propiedad sea: Departamento, PH o Casa
#datos_propiedades_filter %>%
# filter(property_type == "Departamento" | property_type == "PH" | property_type == "Casa")
#De forma más limpia:
datos_propiedades_filter <- datos_propiedades_filter %>%
filter(property_type %in% c("Departamento", "PH", "Casa"))
datos_propiedades_filter
#Departamento -> 57.712
#PH -> 5.851
#Casa -> 3.807
IV.El tipo de operacion sea Venta
datos_propiedades_filter <- datos_propiedades_filter %>%
filter(operation_type == "Venta")
datos_propiedades_filter
Con el filtro de tipo de venta tendríamos un total de 61.905 observaciones.
c.Seleccionar las variables id, l3, rooms, bedrooms, bathrooms, surface_total, surface_covered, price y property_type.
datos_propiedades_filter <- datos_propiedades_filter %>%
select(id, l3, rooms, bedrooms, bathrooms, surface_total, surface_covered, price, property_type)
datos_propiedades_filter
#Deberian llegar a un dataset con 61.905 observaciones y 9 variables.
2.Análisis exploratorios (I) a.Obtener la cantidad de valores únicos y de valores faltantes (NAs) para cada una de estas variables.
Podríamos usar n_distinct para evaluar NA por cada variable, por ejemplo:
n_distinct(datos_propiedades_filter$l3)
[1] 58
Pero con sapply podemos obtener los NA para todo el dataset de forma más sencilla
sapply(datos_propiedades_filter, function(x) sum(is.na(x)))
id l3 rooms bedrooms bathrooms surface_total surface_covered price
0 355 5314 25298 3196 3671 2975 0
property_type
0
Y también los valores únicos
sapply(datos_propiedades_filter, function(x) n_distinct(x))
id l3 rooms bedrooms bathrooms surface_total surface_covered price
61905 58 24 25 15 671 573 4095
property_type
3
La función summary también nos sirve para validar los NAs
summary(datos_propiedades_filter)
id l3 rooms bedrooms bathrooms surface_total surface_covered
Length:61905 Length:61905 Min. : 1.00 Min. : 0.000 Min. : 1.000 Min. : 0.0 Min. : 0.00
Class :character Class :character 1st Qu.: 2.00 1st Qu.: 1.000 1st Qu.: 1.000 1st Qu.: 45.0 1st Qu.: 40.00
Mode :character Mode :character Median : 3.00 Median : 2.000 Median : 1.000 Median : 66.0 Median : 59.00
Mean : 2.79 Mean : 2.052 Mean : 1.517 Mean : 103.9 Mean : 87.06
3rd Qu.: 4.00 3rd Qu.: 3.000 3rd Qu.: 2.000 3rd Qu.: 107.0 3rd Qu.: 93.00
Max. :32.00 Max. :130.000 Max. :14.000 Max. :126062.0 Max. :126062.00
NA's :5314 NA's :25298 NA's :3196 NA's :3671 NA's :2975
price property_type
Min. : 6000 Length:61905
1st Qu.: 115200 Class :character
Median : 169000 Mode :character
Mean : 257556
3rd Qu.: 273000
Max. :45535353
En general se ve alrededor de un 5% faltante de datos, a exepción de la variable bedrooms que presenta un 41% de datos faltantes.
b.Obtener la matriz de correlaciones para las variables numéricas. Pista: usen ‘complete.obs’ para poder omitir los valores faltantes.
Calculando por el método de Pearson (y filtrando las variables numéricas con select) obtemnemos:
correlated_pearson <- cor(datos_propiedades_filter %>%
select(-id, -l3, -property_type)
, use="complete.obs", method="pearson") %>%
correlate() %>% #Para convertir la matrix en un data frame
shave() %>% #Para mostrar sólo lo que está abajo de la diagonal
fashion() #Para redondear decimales y hacerlo más legible
Correlation method: 'pearson'
Missing treated using: 'pairwise.complete.obs'
correlated_pearson
Observamos algunas correlacionesmarcadas y esperadas, como bedrooms<->rooms ,rooms<->bathrooms y surface_total<->surface_covered. Vemos también una correlación alta entre una variable de las que más nos interesan price<->bathrooms.
Sin embargo, vemos algunas correlaciones negativas que llaman mucho la atención: rooms<->surface_total rooms<->surface_covered price<->surface_total price<->surface_covered Esto parecería contradecir la lógica, dado que esperaríamos que una casa de mayor área cuente con mayor cantidad de habitaciones, además de con un precio mayor, lo que en ambos casos implicaría correlaciones positivas.
Un detalle menor sería que la correlación surface_total<->surface_covered parece algo débil para el significado de las variables.
Teniendo en cuenta que el calculo de correlación bajo el método Pearson es bastante sensible a outliers realizamos una nueva matriz de correlación con el método Spearman que es más robusto.
correlated_spearman <- cor(datos_propiedades_filter %>%
select(-id, -l3, -property_type)
, use="complete.obs", method="spearman") %>%
correlate() %>% #Para convertir la matrix en un data frame
shave() %>% #Para mostrar sólo lo que está abajo de la diagonal
fashion() #Para redondear decimales y hacerlo más legible
correlated_spearman
Efectivamente vemos que la correlaciones: rooms<->surface_total rooms<->surface_covered price<->surface_total price<->surface_covered Que nos llamaban la atención para a ser positivas, y además vemos muy marcada la correlación surface_total<->surface_covered.
c.Grafique la matriz de correlaciones usando la librería corrr.
De forma gráfica tenemos bajo el método Pearson:
cor(datos_propiedades_filter %>%
select(-id, -l3, -property_type)
, use="complete.obs", method="pearson") %>%
correlate() %>% #Para convertir la matrix en un data frame
shave() %>% #Para mostrar sólo lo que está abajo de la diagonal
rplot() #Graficamos
De forma gráfica tenemos bajo el método Spearman:
cor(datos_propiedades_filter %>%
select(-id, -l3, -property_type)
, use="complete.obs", method="spearman") %>%
correlate() %>% #Para convertir la matrix en un data frame
shave() %>% #Para mostrar sólo lo que está abajo de la diagonal
rplot() #Graficamos
También si queremos clasificar por tipo de propiedad:
datos_propiedades_filter %>%
select(-id,-l3,) %>% # desestimamos algunas variables
mutate(property_type = factor(property_type)) %>%
ggpairs(.,
title = "GG Pairs por property_type",
mapping = aes(colour = property_type))
d.¿Cómo es la correlación entre las variables surface_total y surface_covered? ¿Y la correlación entre rooms y bathrooms?
surface_total y surface_covered se veían extrañamente correlacionadas de forma negativa bajo el método Pearson, bajo el método Spearman hace más sentido su corelación. El anáñlisis de outliers que se hará más adelante arrojará más información sobre este punto.
Graficamos las variables surface_total y surface_covered
ggplot(datos_propiedades_filter, aes(x = surface_total, y = surface_covered)) +
geom_point()
Se realizan los test análisis de correlación: Para el método Pearson
cor.test(datos_propiedades_filter$surface_total, datos_propiedades_filter$surface_covered, method = "pearson")
Pearson's product-moment correlation
data: datos_propiedades_filter$surface_total and datos_propiedades_filter$surface_covered
t = 229.8, df = 56704, p-value < 2.2e-16
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
0.6901322 0.6986559
sample estimates:
cor
0.6944184
Vemos un p-valor bastante pequeño que nos da la suficiente evidencia muestral para descartar la hipótesis nula, el coeficiente de correlación es 0.69
Ahora con el método Spearman:
cor.test(datos_propiedades_filter$surface_total, datos_propiedades_filter$surface_covered, method = "spearman")
Cannot compute exact p-value with ties
Spearman's rank correlation rho
data: datos_propiedades_filter$surface_total and datos_propiedades_filter$surface_covered
S = 1.1755e+12, p-value < 2.2e-16
alternative hypothesis: true rho is not equal to 0
sample estimates:
rho
0.9613189
El test no arroja un resultado debido a los empates “ties” Se procede a hacer un test Kendall
cor.test(datos_propiedades_filter$surface_total, datos_propiedades_filter$surface_covered, method = "kendall")
Kendall's rank correlation tau
data: datos_propiedades_filter$surface_total and datos_propiedades_filter$surface_covered
z = 306.74, p-value < 2.2e-16
alternative hypothesis: true tau is not equal to 0
sample estimates:
tau
0.8674506
Del mismo modo el p-valor es muy pequeño con lo que tenemos suficiente evidencia para descartar la hipótesis nula. Se observa una corelación marcada entre las dos variables.
Respecto a las variables rooms y bathrooms, estás se encuentran relacionadas de forma positiva para un análisis Pearson, sin embargo se ve una relación de relación fuerte negativa para Spearman.
Graficamos las variables rooms y bathrooms
ggplot(datos_propiedades_filter, aes(x = rooms, y = bathrooms)) +
geom_point()
No pareciera tenerse una correlación lineal entre estas dos variables. Procedemos a hacer tests de correlación:
cor.test(datos_propiedades_filter$rooms, datos_propiedades_filter$bathrooms, method = "pearson")
Pearson's product-moment correlation
data: datos_propiedades_filter$rooms and datos_propiedades_filter$bathrooms
t = 188.08, df = 54966, p-value < 2.2e-16
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
0.6206331 0.6308063
sample estimates:
cor
0.6257463
Ahora con el método Spearman:
cor.test(datos_propiedades_filter$rooms, datos_propiedades_filter$bathrooms, method = "spearman")
Cannot compute exact p-value with ties
Spearman's rank correlation rho
data: datos_propiedades_filter$rooms and datos_propiedades_filter$bathrooms
S = 9.9471e+12, p-value < 2.2e-16
alternative hypothesis: true rho is not equal to 0
sample estimates:
rho
0.6406495
El test no arroja un resultado debido a los empates “ties” Se procede a hacer un test Kendall
cor.test(datos_propiedades_filter$rooms, datos_propiedades_filter$bathrooms, method = "kendall")
Kendall's rank correlation tau
data: datos_propiedades_filter$rooms and datos_propiedades_filter$bathrooms
z = 154.39, p-value < 2.2e-16
alternative hypothesis: true tau is not equal to 0
sample estimates:
tau
0.5701826
En ninguno de los dos casos observamos una correlación fuerte.
e.¿Cómo es la correlación de la variable a explicar, price, con el resto de las variables?
correlated_pearson
Para el método Pearson está relacionada con bathrooms de forma positiva, de la correlación negativa con surface_total y surface_covered ya hablamos.
correlated_spearman
Para un análisis con método Spearman vemos una relación algo débil con surface_total y con surface_covered,se ve también una corelación negativa frente a bedrooms que llama la atención.
3.Limpieza de datos a.En el punto 2 deberían haber encontrado que la variable bedrooms presenta una alta proporción de valores faltantes y que presenta una fuerte correlación con la variable rooms. Por lo tanto, vamos a eliminarla.
datos_propiedades_filter2 <- datos_propiedades_filter %>% select(-bedrooms)
datos_propiedades_filter2
b.Eliminar todos los registros que presentan valores faltantes.
datos_propiedades_filter2 <- drop_na(datos_propiedades_filter2)
datos_propiedades_filter2 <- datos_propiedades_filter2 %>% filter(surface_total >= surface_covered)
datos_propiedades_filter2
c.Eliminar aquellos registros en los cuales la superficie total es menor a la superficie cubierta
#Deberían llegar a un dataset con 50.828 observaciones y 8 variables.
4.Análisis exploratorios (II) a.Crear una nueva variable precio_en_miles que sea la variable price divida por 1000. Obtener estadísticas descriptivas para esta nueva variable (cuartiles, promedio, mínimo y máximo) y realizar un histograma de la misma.
datos_propiedades_filter2$precio_en_miles <- (datos_propiedades_filter2$price)/1000
datos_propiedades_filter2
summary(datos_propiedades_filter2$precio_en_miles)
Min. 1st Qu. Median Mean 3rd Qu. Max.
6.0 119.0 170.0 251.6 270.0 6000.0
Acorde a los cuantiles no veriamos una variabilidad excesiva, el valor máximo parece bastante extremo.
#qplot(datos_propiedades_filter2$precio_en_miles, geom = "histogram")
ggplot(data=datos_propiedades_filter2, aes(precio_en_miles)) +
geom_histogram(breaks=seq(6, 6000, by=10),
#fill="red",
color="#69b3a2",
alpha = .2) +
labs(title="Histograma Precio en Miles", x="Precio en Miles", y="Count")
El histograma revela una moda bastante marcada, y un outlier realmente alto. Graficamos con un límite diferente para ignorar el outlier
#qplot(datos_propiedades_filter2$precio_en_miles, geom = "histogram")
ggplot(data=datos_propiedades_filter2, aes(precio_en_miles)) +
geom_histogram(breaks=seq(6, 1000, by=10),
#fill="red",
color="#69b3a2",
alpha = .2) +
labs(title="Histograma Precio en Miles", x="Precio en Miles", y="Count")
b.Obtener las mismas estadísticas descriptivas de la nueva variable precio_en_miles para cada tipo de propiedad y realizar boxplots paralelos de la variable según tipo de propiedad. ¿Qué diferencias encuentran entre los tipos de propiedad?
Utilizaremos tapply con la función summary para esto:
tapply(datos_propiedades_filter2$precio_en_miles, datos_propiedades_filter2$property_type, summary)
$Casa
Min. 1st Qu. Median Mean 3rd Qu. Max.
20.0 235.0 330.0 433.4 490.0 5000.0
$Departamento
Min. 1st Qu. Median Mean 3rd Qu. Max.
6.0 115.0 164.9 247.4 260.0 6000.0
$PH
Min. 1st Qu. Median Mean 3rd Qu. Max.
32.0 137.0 190.0 218.5 270.0 1500.0
Observamos outliers notables en las casas y los apartamentos, en los PHs también tenemos ouliers pero en una menor magnitud.
ggplot(datos_propiedades_filter2, aes(x = property_type, y = precio_en_miles, group = property_type, fill = property_type))+
geom_boxplot() +
scale_y_continuous(limits = c(0, 6000)) # definimos escala del eje y
El tercer cuartil más 1.5 veces la distancia intercuartil nos da 496.5, esto dejaría algunos valores interesantes por fuera, tomaremos el valor de 1000 para voler a graficar. (Un poco menos que 5 distancias I.Q. adicionales).
ggplot(datos_propiedades_filter2, aes(x = property_type, y = precio_en_miles, group = property_type, fill = property_type))+
geom_boxplot() +
scale_y_continuous(limits = c(0, 1000)) # definimos escala del eje y
Se observa en promedio mayor precio para las casas respecto a los apartamentos y PHs, la variabilidad en las casas también es mayor.
c.Realizar un gráfico con la función ggpairs de las variables numéricas (sin abrir por tipo de propiedad). Comenten los aspectos principales que observan en el gráfico
datos_propiedades_filter2 %>%
select(-id,-l3, -property_type) %>% # desestimamos algunas variables
ggpairs(.,
title = "GGPairs sin agrupación")
Se aprecia una relación entre el precio y la cantidad de habitaciones, incluso una mayor relación entre precio y cantidad de baños. Llama la atención la baja relación entre el precio y las variables de superficie, sin embargo las variables de superficie se ven también poco asociadas a la cantidad de habitaciones.
5.Outliers a.Graficar un scatterplot de la variable precio_en_miles y superficie_total. ¿Detectan alguna anomalía?
ggplot(datos_propiedades_filter2, aes(x = precio_en_miles, y = surface_total)) +
geom_point(alpha = 1/10) +
geom_point(aes(colour = factor(property_type)))
Se tienen outliers de superficie muy marcados que no permiten observar claramente la información. Podría haber casos con información errónea respecto a la superficie. También pareciera haber algunos datos que guardan una relación lineal creciente entre las dos variables.
b.Eliminar los outliers univariados de las variables precio_en_miles, rooms y surface_total. Utilizar y fundamentar el o los criterio/s y métodos que consideren adecuados.
Se toma como criterio eliminar outliers a más de 4.5 Distancias intercuartiles para el caso de precio_en_miles, me parcía interesante ver hasta las propiedades alrededor de 1 millón USD.
summary(datos_propiedades_filter2$precio_en_miles)
Min. 1st Qu. Median Mean 3rd Qu. Max.
6.0 119.0 170.0 251.6 270.0 6000.0
#(270+(270-251))*4.5
#1300
datos_propiedades_filter3 <- datos_propiedades_filter2 %>% filter(precio_en_miles < 1300)
Se toma como criterio eliminar outliers a más de 1.5 Distancias intercuartiles para el caso de rooms
summary(datos_propiedades_filter2$rooms)
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.000 2.000 3.000 2.797 4.000 32.000
#(4+(4-3))*1.5
#7.5
datos_propiedades_filter3 <- datos_propiedades_filter3 %>% filter(rooms < 7.5)
Se toma como criterio separar las propiedades de más de 500 metros y las de menos de 500. El criterio de distancia intercuartil no parecía apropiado, puesto que para 9 Di filtraba los menor a 200 metros, que es una medida esperada para una casa promedio.
summary(datos_propiedades_filter2$surface_total)
Min. 1st Qu. Median Mean 3rd Qu. Max.
12.0 45.0 66.0 96.8 106.0 16725.0
#106+(106-96)*9
#196
datos_propiedades_filer_grandes <- datos_propiedades_filter3 %>% filter(surface_total > 500)
datos_propiedades_filter3 <- datos_propiedades_filter3 %>% filter(surface_total < 500)
Se grafica de nuevo el scatterplot para el dataset filtrado
ggplot(datos_propiedades_filter3, aes(x = precio_en_miles, y = surface_total)) +
geom_point(alpha = 1/10) +
geom_point(aes(colour = factor(property_type)))
6.Análisis exploratorios (III) Repetir los análisis exploratorios realizados en el punto 4 al dataset sin outliers. ¿Detectan algún cambio? Explicar. a.Obtener estadísticas descriptivas para la variable precio_en_miles (cuartiles, promedio, mínimo y máximo) y realizar un histograma de la misma.
summary(datos_propiedades_filter3$precio_en_miles)
Min. 1st Qu. Median Mean 3rd Qu. Max.
6.0 118.0 168.0 222.9 265.0 1299.0
La remoción de outliers no afectó en gran manera los estadísticos descriptivos de la variable precio en miles.
#qplot(datos_propiedades_filter2$precio_en_miles, geom = "histogram")
ggplot(data=datos_propiedades_filter2, aes(precio_en_miles)) +
geom_histogram(breaks=seq(0, 1300, by=10),
#fill="red",
color="#69b3a2",
alpha = .2) +
labs(title="Histograma Precio en Miles", x="Precio en Miles", y="Count")
Observamos una curva con cola alargada hacia la derecha, y con la mayor cantidad de datos alrededor de los 125k para precio en miles.
b.Obtener las mismas estadísticas descriptivas de la nueva variable precio_en_miles para cada tipo de propiedad y realizar boxplots paralelos de la variable según tipo de propiedad. ¿Qué diferencias encuentran entre los tipos de propiedad?
ggplot(datos_propiedades_filter3, aes(property_type, precio_en_miles, group = property_type, fill = factor(property_type)))+
geom_boxplot(alpha = 0.75)
Vemos una precios superiores en las casas en promedio frente a los departamentos y PHs (probablemente por la superficia de las mismas) Vemos una altísima variabilidad en los precios de los departamentos, podría explicarse por la variabilidad de su ubicación respecto a las diferentes zonas de la ciudad.
c.Realizar un gráfico con la función ggpairs de las variables numéricas (sin abrir por tipo de propiedad). Comenten los aspectos principales que observan en el gráfico
datos_propiedades_filter3 %>%
select(-id,-l3, -property_type) %>% # desestimamos algunas variables
ggpairs(.,
title = "GGPairs sin agrupación sin outliers")
Se ve una corelación marcada entre el precio y la superficie de las propiedades, sin embargo en la gráfica no se llega a ver relación lineal. En menor medida se observa también una corelación entre el precio y la cantidad de baños y habitaciones de la propiedad.
7.Modelo lineal a.Realizar un modelo lineal simple para explicar el precio_en_miles en función de las habitaciones (rooms) y otro modelo que explique el precio en función de la superficie total (surface_total).
# Modelo Rooms
modelo_rooms = lm(formula = precio_en_miles ~ rooms, data = datos_propiedades_filter3)
#summary(modelo_rooms)
tidy(modelo_rooms)
# Modelo Superficie Total
modelo_surface = lm(formula = precio_en_miles ~ surface_total, data = datos_propiedades_filter3)
#summary(modelo_surface)
tidy(modelo_surface)
b.Usar la función summary() para obtener informacion de ambos modelos. Explicar el significado de los valores de los coeficientes estimados en cada caso.
# Modelo Rooms
summary(modelo_rooms)
Call:
lm(formula = precio_en_miles ~ rooms, data = datos_propiedades_filter3)
Residuals:
Min 1Q Median 3Q Max
-429.78 -75.11 -19.25 33.02 1078.02
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -0.1502 1.5084 -0.1 0.921
rooms 82.1323 0.5057 162.4 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 138.9 on 49618 degrees of freedom
Multiple R-squared: 0.3471, Adjusted R-squared: 0.3471
F-statistic: 2.637e+04 on 1 and 49618 DF, p-value: < 2.2e-16
Se tiene como intercepto con el eje y -0.150, el aumento por cada unidad de la variable habitación representa un aumento de 82k en el precio.
# Modelo Superficie Total
summary(modelo_surface)
Call:
lm(formula = precio_en_miles ~ surface_total, data = datos_propiedades_filter3)
Residuals:
Min 1Q Median 3Q Max
-949.00 -43.49 -17.42 22.56 1026.68
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 53.269372 0.911455 58.44 <2e-16 ***
surface_total 2.001306 0.008692 230.24 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 119.5 on 49618 degrees of freedom
Multiple R-squared: 0.5165, Adjusted R-squared: 0.5165
F-statistic: 5.301e+04 on 1 and 49618 DF, p-value: < 2.2e-16
Se parte del intercepto en 53k por el aumento en superficia (1metro cuadrado) el valor de la propiedad aumenta en 2k.
c.¿Cuál modelo usarían para predecir el precio? ¿Por qué?
El modelo por habitaciones tiene un r-squared de 0.3471 lo que es menor al r-squared del modelo de superficie que es de 0.5165. El segundo modelo explica mejor la variabilidad de los datos, lo escogería.
Sin embargo no descartaría el primero pues aporta entendimiento desde una variable muy importante al momento de elegir una casa.
Viendo gráficamente tenemos el modelo de rooms:
ggplot(datos_propiedades_filter3, aes(rooms, precio_en_miles)) +
#geom_point(size = 2, colour = "#063b36") +
geom_abline(intercept = -0.1502, slope = 82.1323, color="firebrick") +
geom_point(aes(colour = factor(property_type)))
ggplot(datos_propiedades_filter3, aes(surface_total, precio_en_miles)) +
#geom_point(size = 2, colour = "#063b36") +
geom_point(aes(colour = factor(property_type))) +
geom_abline(intercept = 53.269372, slope = 2.001306, color="firebrick")